import os
import json
import time
from openai import OpenAI

# 初始化OpenAI客户端
client = OpenAI(
    base_url="https://ark.cn-beijing.volces.com/api/v3",
    api_key="330f54b7-915b-48a9-9599-c5e47c118cb5"  # 建议改为环境变量读取：os.getenv("ARK_API_KEY")
)


def get_reasons_with_prob(question: str) -> dict:
    """
    调用API仅获取问题的原因及概率（不做唯一性判断）
    """
    # 构建系统提示词：明确禁止LLM判断唯一性，仅输出原因和概率
    system_prompt = """
    你是拓竹科技3D打印领域的专家，需完成以下任务：
    1. 分析用户提出的3D打印问题，判断问题答案是否唯一；不唯一：列出该问题出现的所有可能原因；
    2. 为每个原因分配合理概率，所有原因的概率之和必须为100%（概率需带百分号）；
    3. 严格按照以下JSON格式输出结果（仅保留这两个字段，禁止添加其他字段）：
    {
        "用户问题": "用户的原始问题",
        "原因及概率": [
            {"原因": "具体原因描述", "概率": "XX%"}
        ]
    }
    参考案例：
    [
        {
            "用户问题": "我能打印16色吗？",
            "原因及概率": [
                {"原因": "用户未明确打印机型号，不同型号支持色数不同", "概率": "90%"},
                {"原因": "用户混淆打印色数与材料组合概念", "概率": "10%"}
            ]
        },
        {
            "用户问题": "我的A1 mini能打印16色吗？",
            "原因及概率": [
                {"原因": "A1 mini本身不支持直接打印16色，但通过官方配件AMS Lite可实现最多4色的自动切换打印", "概率": "100%"}
            ]
        }
    ]
    注意：无需判断解决办法是否唯一，仅输出上述两个字段即可！
    """

    try:
        # 调用API获取原因及概率
        response = client.chat.completions.create(
            model="deepseek-v3-1-250821",
            messages=[
                {"role": "system", "content": system_prompt.strip()},
                {"role": "user", "content": question}
            ]
        )

        # 解析API返回结果
        response_content = response.choices[0].message.content.strip()
        if response_content.startswith('[') and response_content.endswith(']'):
            result = json.loads(response_content)[0]  # 处理列表格式
        else:
            result = json.loads(response_content)

        # 验证必要字段是否存在
        if "用户问题" not in result or "原因及概率" not in result:
            raise KeyError("API返回缺少必要字段（用户问题/原因及概率）")
        if not isinstance(result["原因及概率"], list) or len(result["原因及概率"]) == 0:
            raise ValueError("原因及概率列表为空或格式错误")

        return result

    except json.JSONDecodeError:
        return {
            "用户问题": question,
            "原因及概率": [{"原因": "API返回格式错误，无法解析", "概率": "100%"}]
        }
    except (KeyError, ValueError) as e:
        return {
            "用户问题": question,
            "原因及概率": [{"原因": f"API返回数据异常：{str(e)}", "概率": "100%"}]
        }
    except Exception as e:
        return {
            "用户问题": question,
            "原因及概率": [{"原因": f"获取原因失败：{str(e)}", "概率": "100%"}]
        }


def judge_uniqueness_by_code(reasons: list) -> str:
    """
    纯代码逻辑判断解决办法是否唯一
    规则：
    1. 原因唯一 → 解决办法唯一
    2. 原因不唯一但存在概率>85%的原因 → 解决办法唯一
    3. 其他情况 → 解决办法不唯一
    """
    if len(reasons) == 1:
        return "是"
    # 遍历原因，检查是否有概率>85%的项
    for reason in reasons:
        try:
            prob = int(reason["概率"].strip('%'))
            if prob > 85:
                return "是"
        except (ValueError, KeyError):
            # 概率格式错误时，默认按"不唯一"处理
            return "否"
    return "否"


def get_core_reason(reasons: list) -> str:
    """提取核心原因（用于生成客服回答）"""
    if len(reasons) == 1:
        return reasons[0]["原因"]
    for reason in reasons:
        try:
            prob = int(reason["概率"].strip('%'))
            if prob > 90:
                return reason["原因"]
        except (ValueError, KeyError):
            pass
    return "问题原因未明确"


def generate_customer_service_reply(question: str, core_reason: str) -> str:
    """生成符合要求的客服回答"""
    system_prompt = """
    你是拓竹科技官方客服，针对用户的3D打印问题，给出简洁、准确的解决方案：
    1. 基于提供的核心原因，直接给出可执行的操作步骤，避免冗余；
    2. 语气亲切专业，使用“您”的称谓，结尾可加简短关怀语（如“有其他问题随时咨询~”）；
    3. 严格按照以下JSON格式输出，仅保留“客服回答”字段，禁止添加其他内容：
    {"客服回答": "具体回复内容"}
    示例：
    输入问题：我的A1 mini能打印16色吗？
    输入核心原因：A1 mini 本身不支持直接打印16色
    输出：{"客服回答": "您的A1 mini 本身不支持直接打印16色，但通过官方配件AMS Lite可实现最多4色的自动切换打印"}
    """

    try:
        response = client.chat.completions.create(
            model="deepseek-v3-1-250821",
            messages=[
                {"role": "system", "content": system_prompt.strip()},
                {"role": "user", "content": f"用户问题：{question}\n核心原因：{core_reason}"}
            ]
        )

        response_content = response.choices[0].message.content.strip()
        reply_data = json.loads(response_content)
        return reply_data.get("客服回答", "抱歉，暂未获取到有效解决方案。")
    except Exception as e:
        return f"生成回答失败：{str(e)}"


def process_json_file(json_path: str) -> str:
    """
    读取JSON文件中的"修正后问题"，判断唯一性并生成结果（含客服回答）
    """
    try:
        # 读取JSON文件
        with open(json_path, 'r', encoding='utf-8') as f:
            json_data = json.load(f)

        # 提取"修正后问题"列表
        questions = []
        for item in json_data:
            if "修正后问题" not in item:
                raise KeyError("JSON条目缺少'修正后问题'字段")
            question = item["修正后问题"].strip()
            if question:  # 过滤空问题
                questions.append(question)

        total_questions = len(questions)
        print(f"共检测到{total_questions}个有效问题，开始处理...\n")

        # 记录总处理时间
        total_start_time = time.time()

        # 处理每个问题并生成结果
        result = []
        service_replies = []  # 单独存储客服回答结果
        for idx, q in enumerate(questions, 1):
            start_time = time.time()
            print(f"正在处理第{idx}/{total_questions}个问题：{q}")

            # 步骤1：获取原因及概率
            reason_data = get_reasons_with_prob(q)
            reasons = reason_data["原因及概率"]

            # 步骤2：判断唯一性
            is_unique = judge_uniqueness_by_code(reasons)

            # 步骤3：若唯一，生成客服回答
            customer_reply = None
            if is_unique == "是":
                core_reason = get_core_reason(reasons)
                customer_reply = generate_customer_service_reply(q, core_reason)
                service_replies.append({"序号": idx, "用户问题": q, "客服回答": customer_reply})

            # 构建最终结果字典
            final_item = {
                "序号": idx,
                "用户问题": reason_data["用户问题"],
                "原因及概率": reasons,
                "解决办法是否唯一": is_unique,
                "客服回答": customer_reply if is_unique == "是" else None
            }
            result.append(final_item)

            # 打印单个问题处理信息
            elapsed_time = round(time.time() - start_time, 2)
            print(f"第{idx}个问题处理完成，耗时：{elapsed_time}秒，解决办法{'唯一' if is_unique == '是' else '不唯一'}\n")

        # 打印总耗时
        total_elapsed = round(time.time() - total_start_time, 2)
        print(f"所有问题处理完成！总耗时：{total_elapsed}秒\n")

        # 保存客服回答结果到单独文件
        with open("客服回答结果.json", "w", encoding="utf-8") as f:
            json.dump(service_replies, f, ensure_ascii=False, indent=2)
        print("客服回答结果已保存至：客服回答结果.json")

        # 转换为JSON字符串（确保中文正常显示）
        return json.dumps(result, ensure_ascii=False, indent=2)

    except FileNotFoundError:
        return json.dumps({"错误": f"文件不存在：{json_path}"}, ensure_ascii=False)
    except json.JSONDecodeError:
        return json.dumps({"错误": f"JSON文件解析失败：{json_path}"}, ensure_ascii=False)
    except KeyError as e:
        return json.dumps({"错误": f"JSON结构错误：{str(e)}"}, ensure_ascii=False)
    except Exception as e:
        return json.dumps({"错误": str(e)}, ensure_ascii=False)


if __name__ == "__main__":
    # JSON文件路径（根据实际文件位置调整）
    json_path = "不唯一案例补充修正结果.json"

    # 处理并生成结果
    json_result = process_json_file(json_path)

    # 打印并保存唯一性判断结果
    print("最终唯一性判断结果：")
    print(json_result)

    with open("问题唯一性判断结果json.json", "w", encoding="utf-8") as f:  # 修正文件名笔误
        f.write(json_result)
    print("\n结果已保存至：问题唯一性判断结果json.json")